package cn.qu.phizline;

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import cn.qu.phizline.common.ByteBuffer;
import cn.qu.phizline.connect.AppRTCClient;
import cn.qu.phizline.connect.WebSocketRTCClient;
import cn.qu.phizline.connect.handle.Handle;
import cn.qu.phizline.connect.handle.InitHandle;
import cn.qu.phizline.connect.handle.LoginHandle;
import cn.qu.phizline.event.Payload;
import cn.qu.phizline.event.common.ResponseEvent;
import cn.qu.phizline.event.init.InitEvent;
import cn.qu.phizline.event.login.LoginEvent;

import static cn.qu.phizline.activity.IntentExtraKeys.TOKEN;

/**
 * Created by zh on 2017/10/25.
 */

public class PhizlineApplication extends Application {

    //服务访问接口
    private static AppRTCClient appRtcClient;
    private static Context context;

    private void initConnect() {
        //创建服务请求对象
        appRtcClient = new WebSocketRTCClient("ws://192.168.31.143:8080/ws");
        appRtcClient.connect();
    }

    public static AppRTCClient getClient() {
        return appRtcClient;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        context = this;
        initConnect();

    }


    public static void putAttr(String key, String val) {
        SharedPreferences sp = context.getSharedPreferences("SYSTEM", MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(key, val);
        editor.commit();
    }

    public static String getAttr(String key, String defaultVal) {
        SharedPreferences sp = context.getSharedPreferences("SYSTEM", MODE_PRIVATE);
        return sp.getString(key, defaultVal);
    }

    public static String getToken() {
        return PhizlineApplication.getAttr(TOKEN, "");
    }

    public static String getDeviceId() {
        return "deviceid";
    }

    public static void setToken(String token) {
        PhizlineApplication.putAttr(TOKEN, token);
    }

    private static ProtoTypes protoTypes = new ProtoTypes();

    public static ProtoTypes getProtoTypes() {
        return protoTypes;
    }

    static {
        protoTypes.register(InitEvent.class, InitHandle.class);
        protoTypes.register(LoginEvent.class, LoginHandle.class);
    }

    public static class ProtoTypes {
        private final Logger logger = LoggerFactory.getLogger(ProtoTypes.class);

        private Map<String, Class<? extends Payload>> payloadMap = new ConcurrentHashMap<>();
        private Map<String, Class<? extends Handle>> handleMap = new ConcurrentHashMap<>();

        public void register(Class<? extends Payload> payloadClazz, Class<? extends Handle> handleClass) {
            try {
                Payload payload = payloadClazz.newInstance();
                String key = getPayloadKey(payload.getType(), payload.getVersion());
                payloadMap.put(key, payloadClazz);
                handleMap.put(key, handleClass);
            } catch (InstantiationException e) {
                logger.error(e.getMessage(), e);
            } catch (IllegalAccessException e) {
                logger.error(e.getMessage(), e);
            }
        }

        public Class<? extends Payload> getType(String key) {
            return payloadMap.get(key);
        }

        public Class<? extends Handle> getHandleType(String key) {
            return handleMap.get(key);
        }

        public <T extends Payload> T load(byte[] bytes) {
            ByteBuffer buffer = new ByteBuffer(bytes);

            int type = buffer.uint4();
            int version = buffer.uint4();
            int len = buffer.uint8();

//            Class<? extends Payload> clazz = payloadMap.get(getPayloadKey(type, version));

            Payload payload = new AndroidPayloadConventer().fromBytes(ResponseEvent.class, buffer.read(len));
            return (T) payload;
        }

        public String getPayloadKey(int type, int version) {
            return String.format("%s_%s", type, version);
        }

    }
}
